#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "led.h"
/**
	* @brief  SS写。其中A4输出片选信号SS
	* @retval None
  */
void MySPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

/**
	* @brief  SCK写。其中A5输出时钟信号SCK
	* @retval None
  */
void MySPI_W_SCK(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
}

/**
	* @brief  MOSI写。其中A7输出主对从写入的内容MOSI
	* @retval None
  */
void MySPI_W_MOSI(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);
}

/**
	* @brief  MISO读。其中A6输入从对主写入的内容MISO
	* @retval None
  */
uint8_t MySPI_R_MIS0(void)
{
	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}

/**
	* @brief  进行SPI初始化，将采用SPI模式0进行通信。SPI要求主机的输入引脚初始化为浮空或上拉输入，输出为推挽输出。此处默认采用A4输出片选信号；A5输出时钟信
						号；A6：从机输出，主机输入；A7：主机输出，从机输入。这与STM32硬件进行SPI通信用到的引脚是相同的。其中对于主机STM32而言，A4、A5、A7都是输出引
						脚，A6是输入引脚
  * @retval None
  */
void MySPI_Init(void)
{
	gpio_Init(RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7, GPIO_Mode_Out_PP);//推挽输出
	gpio_Init(RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_6, GPIO_Mode_IPU);//A6是从机的D0输出，该GPIO引脚需要为浮空或上拉输入。此处选择上拉输入
	MySPI_W_SS(1);//从机失能，默认不与它进行通信
	MySPI_W_SCK(0);//SPI模式0下时钟信号初始为低
}

/**
	* @brief  SPI起始命令，即从机使能
  * @retval None
  */
void MySPI_Start(void)
{
	MySPI_W_SS(0);
}

/**
	* @brief  SPI终止命令，即从机失能
  * @retval None
  */
void MySPI_Stop(void)
{
	MySPI_W_SS(1);
}

/**
* @brief  模式0下进行SPI互换字节
	* @param  GPIOx: 哪一片GPIO（从如下选项中选择）
	* @retval 从机发来的一字节数据
  */
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	uint8_t i, ByteReceive = 0x00;
	for(i=0;i<8;i++)
	{
		MySPI_W_MOSI(ByteSend & (0x80 >> i));//SS（最初始）或SCK（后续）下降沿后数据移出
		MySPI_W_SCK(1);
		if(MySPI_R_MIS0() == 1)
		{
			ByteReceive |= (0x80 >> i);
		}//SCK上升沿后数据移入
		MySPI_W_SCK(0);
	}
	return ByteReceive;
}
